#include <iostream>
#include <fstream>
#include <iomanip>

#include <signal.h>
#include <sys/types.h>
#include <fcntl.h>

#include "IOError.h"
#include "DigitalIO_DL636F.h"
#include "Counter_DL636G1.h"
#include "QDC_V792.h"
#include "EventStruct.h"
#include "timemeasure.h"

char *devfn="/tmp/sis1100_00remote";
bool quit = false;

//use channels 0 to 11
const static u_int32_t USED_CHANNELS  = 0xfff;
const static u_int32_t USED_THRESHOLD = 0x000;

void sigint_handler(int sig);

int main(int argc,char *argv[])
{
		const static u_int32_t BUFSIZE = 1000;
		EventStruct ev[BUFSIZE]; //events
		u_int32_t   qdc_ptr=0;
		
		//install handler for CTRL-C
		signal(SIGINT,sigint_handler);
		
		cerr << "test_QDC_V792" << endl << endl;
		
		int crate;
		if( !(crate=open(devfn, O_RDWR, 0)) )
		{
				cerr << "ERROR: could not open \"" << devfn << "\"" << endl;
				exit(1);
		}
		
		cerr << "vme reset...";
		vmesysreset(crate);
		cerr << "ok" << endl;
	
		DigitalIO_DL636F   io(crate,0x9900);
		Counter_DL636G1  cnt1(crate,0x9920);
		QDC_V792          qdc(crate,0x25390000);
	
		cerr << "using qdc @0x" << hex << qdc.getAddress()
         << ", cnt1 @0x" << cnt1.getAddress()
				 << ", io @0x" << io.getAddress() << dec << endl << endl;

		u_int32_t rc=0,hc=0,delta=0;
		try {
				io.setOutputs(0);
				cnt1.reset();
				cerr << "resetting qdc: ";
		
				cerr << "SoftwareReset..."; qdc.SoftwareReset(); cerr << "ok";
				cerr << ", DefineChannelBehaviour...";
				qdc.DefineChannelBehaviour(USED_CHANNELS,	USED_THRESHOLD);
				cerr << "ok";
				cerr << ", CountOnlyValidEvents...";
				qdc.CountOnlyValidEvents(); cerr << "ok";
				cerr << ", SetFastClearWindow()...";
				qdc.SetFastClearWindow(0); cerr << "ok";
				cerr << ", ClearBit2Pattern()...";
				qdc.ClearBit2Pattern( QDC_V792::BITSET_2_OVER_RANGE_ENABLED |
															QDC_V792::BITSET_2_LOW_THRESHOLD_ENABLED); 
				cerr << "ok";
				
		cerr << "\n\nmeasuring, press CTRL-C to quit" << endl;
		
		io.setO2(1);
		TM_INIT();
		TM_START();
		io.setO1(1);
		
		while(!quit) {
				
				hc=cnt1.getC();
				delta=hc-rc;

				cerr << "hc=" << hc
						 << " rc=" << rc
						 << " -> delta=" << delta
						 << endl;

				if(delta>0) {
						qdc.ReadEvents(ev,delta);
						
						rc      += delta;
						qdc_ptr += delta;						
				}

				for(u_int32_t j=0; j < delta; j++) {
				    
						u_int16_t *qdc = (u_int16_t*)(&ev[j]);
						for(u_int32_t i=0; i<12; i++)
								cout << " " << qdc[i];
						cout << endl;
				}
				
		}    
    io.setO1(0);
		TM_STOP();
		io.setO2(0);
		
		//TODO: read rest...
		
		
		} catch(IOError ioe) {
				TM_STOP();
				io.setOutputs(0);

				cerr << "catched IOError exception: " << ioe.getMsg() << endl 
						 << "param=0x" << hex << ioe.getParam() << dec << endl << endl;
		}
		
		cerr << "got " << rc << " events in " << tm_secs << " seconds, rate = "
				 << rc/tm_secs << " Hz" << endl;

		cerr << "closing crate..."; close(crate); cerr << "ok\n\n";
		
		return 0;
}


void sigint_handler(int sig)
{
		cerr << "CTRL-C pressed" << endl;
		
		quit=true;
}
